package ui.magic.magicui.container.Absolute;

import android.content.Context;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AbsoluteLayout;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import ui.magic.magicui.container.Base.MagicInterface;
import ui.magic.magicui.container.Base.MagicType;
import ui.magic.magicui.container.View.Observer.ChangeItemObserver;

/**
 * Created by liushiyin on 2017/10/23.
 */

/**
 *MagicUi的绝对布局
 * 你可像绝对布局一样指定子节点的位置和大小，当然这都是相对于父节点的位置和大小
 * 比如你在添加子节点时如下使用addChildView(button,5,5,20,20),
 * 这将表示子节点相对于父节点左上角，向右移父节点宽度的5%大小，
 * 向下移相对于父节点的高度的5%大小，子节点的宽度为父节点的20%，
 * 子节点的高度为父节点的20%
 */
public class AbsoluteMagicUi extends AbsoluteLayout implements MagicInterface{

    private Point magicSize;   //保存UI组件尺寸
    private FVector location;   //保存UI组件位置
    private Map<View,Params> viewTrees;
    private Map<MagicInterface,Params> magicTrees;
    private MagicType type;

    /*
      *在自己的尺寸改变时调整子组件的大小
     */
    private void reOrderChildSize(){
        Iterator iterator=viewTrees.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry entry=(Map.Entry)iterator.next();
            View v=(View) entry.getKey();
            Params params=(Params) entry.getValue();
            super.removeView(v);
            addChildViewTmp(v,params.perx,params.pery,params.perW,params.perH);
        }
        Iterator iterator1=magicTrees.entrySet().iterator();
        while(iterator1.hasNext()){
            Map.Entry entry=(Map.Entry)iterator1.next();
            MagicInterface magic=(MagicInterface)entry.getKey();
            Params params=(Params)entry.getValue();
            super.removeView((View)magic);
            addChildMagicTmp(magic,params.perx,params.pery,params.perW,params.perH);
        }
    }

    /*
    *设置UI组件大小，同时会调整子组件大小，自己不要轻易调用此函数，
    *而应有UI组件自身在适当的时候调用
    *@Param width：宽度
    *@Param height：高度
     */
    @Override
    public void setMagicSize(int width, int height) {
        magicSize.x=width;
        magicSize.y=height;
        reOrderChildSize();
    }

    public AbsoluteMagicUi(Context context) {
        super(context);
        init(MagicType.As_Child);
    }

    public AbsoluteMagicUi(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(MagicType.As_Child);
    }

    public AbsoluteMagicUi(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(MagicType.As_Child);
    }

    /*
    *进行一些初始化操作
     */
    public void init(MagicType type){
        this.type=type;
        magicSize=getWindowSize();
        location=new FVector();
        viewTrees=new HashMap<>();
        magicTrees=new HashMap<>();
    }

    /*
    *添加View子节点
    * @Param v：View子节点
    * @Param perx：字节点相对于父节点的x坐标（0~100的浮点数，表示子节点相对于父节点坐标占父节点大小的百分比）
    * @Param pery:字节点相对于父节点的y坐标（0~100的浮点数，表示子节点相对于父节点坐标占父节点大小的百分比）
    * @Param perWidth：0~100的浮点数表示子节点宽度为父节点宽度的百分比值
    * @Param perHeight：0~100的浮点数表示子节点宽度为父节点高度的百分比值
     */
    public void addChildView(View v,float perx,float pery,float perWidth,float perHeight){
        addChildViewTmp(v,perx,pery,perWidth,perHeight);
        viewTrees.put(v,new Params(perx,pery,perWidth,perHeight));
    }

    /*
    *addViewTmp的中间过程
     */
    private void addChildViewTmp(View v,float perx,float pery,float perWidth,float perHeight){
        float rex=(perx/MAX)*magicSize.x;
        float rey=(pery/MAX)*magicSize.y;
        float rew=(perWidth/MAX)*(float) magicSize.x;
        float reh=(perHeight/MAX)*(float) magicSize.y;
        LayoutParams params=new LayoutParams((int) rew,(int) reh,(int) rex,(int) rey);
        super.addView(v,params);
    }

    /*
    *添加MagicUi字节点，也即继承了MagicInterface的组件
    * @Param magic：MagicUi子节点
    * @Param perx：字节点相对于父节点的x坐标（0~100的浮点数，表示子节点相对于父节点坐标占父节点大小的百分比）
    * @Param pery:字节点相对于父节点的y坐标（0~100的浮点数，表示子节点相对于父节点坐标占父节点大小的百分比）
    * @Param perWidth：0~100的浮点数表示子节点宽度为父节点宽度的百分比值
    * @Param perHeight：0~100的浮点数表示子节点宽度为父节点高度的百分比值
     */
    public void addChildMagicUi(MagicInterface magic,float perx,float pery,float perWidth,float perHeight){
        addChildMagicTmp(magic,perx,pery,perWidth,perHeight);
        magicTrees.put(magic,new Params(perx,pery,perWidth,perHeight));
    }

    /*
    *addChildMagicUi的中间过程
     */
    private void addChildMagicTmp(MagicInterface magic,float perx,float pery,float perWidth,float perHeight){
        float rex=(perx/MAX)*magicSize.x;
        float rey=(pery/MAX)*magicSize.y;
        float rew=(perWidth/MAX)*(float) magicSize.x;
        float reh=(perHeight/MAX)*(float) magicSize.y;
        LayoutParams params=new LayoutParams((int) rew,(int) reh,(int) rex,(int) rey);
        magic.setMagicSize((int) rew,(int) reh);
        magic.setLocation(perx,pery);
        super.addView((View) magic,params);
    }

    /*
    *获取子节点相对于父节点的百分比位置
    * @Param v：子节点
    * @return FVector：成功则返回子节点相对于父节点的百分比位置，失败则返回坐标值为（-1，-1）的向量
     */
    public FVector getChildPerSize(View v){
        Params pa=viewTrees.get(v);
        if(pa==null){
            Params pa1=magicTrees.get(v);
            if(pa1==null){
                return new FVector(-1,-1);
            }else{
                return new FVector(pa1.perW,pa1.perH);
            }
        }else{
            return new FVector(pa.perW,pa.perH);
        }
    }

    /*
    *获取子节点相对于父节点的百分比位置
    * @Parma v：子节点
    * @return FVector：成功则返回子节点相对于父节点的百分比位置，失败测返回（-1，-1）的向量
     */
    public FVector getChildPerLocation(View v){
        Params pa=viewTrees.get(v);
        if(pa==null){
            Params pa1=magicTrees.get(v);
            if(pa1==null){
                return new FVector(-1,-1);
            }else{
                return new FVector(pa1.perx,pa1.pery);
            }
        }else{
            return new FVector(pa.perx,pa.pery);
        }
    }

    /*
    *获取自身的真实位置以像素为单位
    * @return FVector：自身的真实位置
     */
    public FVector getLocation(){
        FVector vector=new FVector();
        vector.x=location.x;
        vector.y=location.y;
        return vector;
    }

    /*
    *设置组件的位置，任何情况下不要自己去调用本函数，而应由组件自身在适当的情况下调用
    * @Param x:组件的x坐标，像素点为单位
    * @Param y：组件的y坐标，像素点为单位
     */
    @Override
    public void setLocation(float x,float y) {
        location.x = x;
        location.y = y;
    }

    /*
    *调整子节点的位置
    *@param child:需要调整位置的字节点
    * @param perx：新位置的相对x坐标
    * @Param pery：新位置的相对y坐标
    */
    public boolean changeChildLocation(View child,float perx,float pery){
        Params params=viewTrees.get(child);
        if(params==null){
            Params params1=magicTrees.get(child);
            if(params1==null){
                return false;
            }else{
                Change(child,perx,pery,params1.perW,params1.perH,params,1);
                return true;
            }
        }else{
            Change(child,perx,pery,params.perW,params.perH,params,2);
            return true;
        }
    }

    /*
    *调整子节点的相对尺寸
    *@Param child:需要调整的子节点
    * @Param perWidth：新的百分比大小
    * @Param perHeight：新的百分比大小
     */
    public boolean changeChildSize(View child,float perWidth,float perHeight){
        Params params=viewTrees.get(child);
        if(params==null){
            Params params1=magicTrees.get(child);
            if(params1==null){
                return false;
            }else{
                Change(child,params1.perx,params1.pery,perWidth,perHeight,params,1);
                return true;
            }
        }else{
            Change(child,params.perx,params.pery,perWidth,perHeight,params,2);
            return true;
        }
    }

    private void Change(View child,float perx,float pery,float perWidth,float perHeight,Params params,int flag){
        params.perx=perx;
        params.pery=pery;
        params.perW=perWidth;
        params.perH=perHeight;
        super.removeView(child);
        if(flag==1){
            addChildMagicTmp((MagicInterface) child,params.perx,params.pery,params.perW,params.perH);
        }else {
            addChildViewTmp(child,params.perx,params.pery,params.perW,params.perH);
        }
    }

    /*
    *移除View子节点
     */
    public void removeChildView(View view){
        viewTrees.remove(view);
    }

    /*
    *移除MagicUi子节点
     */
    public void removeChildMagicUi(MagicInterface magic){
        magicTrees.remove(magic);
    }

    /*
    *获取手机屏幕的大小
    * @return Point：保存手机屏幕大小的向量
     */
    public Point getWindowSize(){
        WindowManager wm=(WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
        Point point=new Point();
        wm.getDefaultDisplay().getSize(point);
        return  point;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if(type==MagicType.Self_Init){
            int[] locations=new int[2];
            getLocationInWindow(locations);
            if(location.x!=locations[0]||location.y!=locations[1]){
                int width=getMeasuredWidth();
                int height=getMeasuredHeight();
                setLocation(locations[0],locations[1]);
                setMagicSize(width,height);
            }
        }
    }

    public void setSelfInit(){
        type=MagicType.Self_Init;
    }

    public void setAsChild(){
        type=MagicType.As_Child;
    }

    /*
        *以下函数废弃不再使用，不要尝试使用它们，不保证使用后会发生什么错误
         */
    @Override
    @Deprecated
    public void addView(View child) {super.addView(child);}
    @Override
    @Deprecated
    public void addView(View child, int index) {super.addView(child, index);}
    @Override
    @Deprecated
    public void addView(View child, int width, int height) {super.addView(child, width, height);}
    @Override
    @Deprecated
    public void addView(View child, ViewGroup.LayoutParams params) {super.addView(child, params);}
    @Override
    @Deprecated
    public void addView(View child, int index, ViewGroup.LayoutParams params) {super.addView(child, index, params);}

    @Override
    @Deprecated
    public void removeView(View view) {super.removeView(view);}
    @Override
    @Deprecated
    public void removeViewAt(int index) {super.removeViewAt(index);}
    @Override
    @Deprecated
    public void removeAllViews() {super.removeAllViews();}
}
